require 'rubygems'
require 'progressbar'
require 'merge/mservices'
require 'csv'

module Merge
  
  class ProfileMerger
    
    public
    
    def initialize(opt = {})
      @conditions = !opt[:conditions].nil? ? opt[:conditions] : "last_update IS NULL"
      #@services = opt[:rules] ? opt[:rules] : {}
      reset_statistic
    end
    
    def reset_statistic
      @stat = {}
      mf = Merge::Fields.instance
      mf.collect {|f| @stat[f.name] = Hash.new 0}
    end
    
    def get_statistic
      require 'merge/field'
      @stat
    end
    
    def start_merge
      reset_statistic
      record_to_create = User.count_by_sql "SELECT count(*) FROM #{MedialProfile.table_name} WHERE #{@conditions}"
      
      pbar = ProgressBar.new("merging", 100)
      last_progress_value = 0
      progress_value = last_progress_value
      records_analyzed = 0
      
      MedialProfile.find_each(:conditions => @conditions) { |m|
        
        merge m
        
        records_analyzed += 1
        progress_value = sprintf("%d", records_analyzed.to_f / record_to_create * 100.0).to_i
        if  progress_value != last_progress_value then
          last_progress_value = progress_value
          pbar.set progress_value
        end
      }        
      
      puts pbar.finish
    end
    
    def update_data_chunk
      record_to_create = User.count_by_sql "SELECT count(*) FROM #{User.table_name}"
      
      pbar = ProgressBar.new("#{MedialProfile.table_name}", 100)
      last_progress_value = 0
      progress_value = last_progress_value
      records_analyzed = 0
      
      User.find_each { |c|
        c.create_medial_profile if c.medial_profile.nil?
        
        records_analyzed += 1
        progress_value = sprintf("%d", records_analyzed.to_f / record_to_create * 100.0).to_i
        if  progress_value != last_progress_value then
          last_progress_value = progress_value
          pbar.set progress_value
        end
      }        
      
      puts pbar.finish
    end
    
    protected
    
    def merge(medial_profile)
      ms =  Merge::MServices.instance
      mf = Merge::Fields.instance
      
      services = ms.filter_services medial_profile.user.services
      medial_profile.service_count = services.length
      #puts "count #{services.length}"
      #services.each {|s| p s}
      count_overlap = {}
      mf.collect {|f| count_overlap[f.name] = 0}
      
      mf.collect { |f|
      
        medial_profile.send "#{f.name.to_s}=", nil #clean old value  
        p_field = f.get_probabilistic_field services
        val = ""
        
        CSV::Writer.generate(val) { |csv|
          p_field.each_pair {|k,v|
            csv << [k,v]
          }
          medial_profile.send "#{f.name.to_s}=", val unless val.eql?("")
        }
      }
      
      medial_profile.last_update = DateTime.now.strftime "%F %T"
      medial_profile.save
      
      services.each { |s|
        if s.used == false then
          s.used = true
          s.save
        end
      }
      
      count_overlap.each_pair {|k,v| @stat[k][v] += 1 }
    end
    
  end
  
end